import java.io.*;
import java.net.*;
import java.util.Random;

public class UDPServer {
    private static final int PORT = 9876;   // 服务器端口
    private static final double LOSS_RATE = 0.3; // 丢包率
    private static final int AVERAGE_DELAY = 100; // 延迟100ms

    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(PORT);
        Random random = new Random();

        while (true) {
            DatagramPacket requestPacket = new DatagramPacket(new byte[1024], 1024);
            socket.receive(requestPacket);
            String message = new String(requestPacket.getData(), 0, requestPacket.getLength());

            if (message.equals("SYN")) {
                sendResponse(socket, requestPacket, "SYN-ACK");
                continue;
            } else if (message.equals("ACK")) {
                System.out.println("Connection established.");
                continue;
            } else if (message.equals("FIN")) {
                sendResponse(socket, requestPacket, "ACK");
                System.out.println("Connection closed.");
                continue;
            }

            if (random.nextDouble() < LOSS_RATE) {
                System.out.println("Packet loss, pretending to not receive the packet.");
                continue;
            }

            // 模拟延迟
            try {
                Thread.sleep((int) (random.nextDouble() * 2 * AVERAGE_DELAY));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 生成响应消息
            String sequenceNumber = message.substring(message.indexOf("Seq:") + 4, message.indexOf(",Ver:"));
            String responseMessage = "Seq:" + sequenceNumber + ",Time:" + java.time.LocalTime.now().toString();
            byte[] buffer = responseMessage.getBytes();
            DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length, requestPacket.getAddress(), requestPacket.getPort());

            socket.send(responsePacket);
            System.out.println("Sent: " + responseMessage);
        }
    }

    private static void sendResponse(DatagramSocket socket, DatagramPacket requestPacket, String message) throws IOException {
        byte[] buffer = message.getBytes();
        DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length, requestPacket.getAddress(), requestPacket.getPort());
        socket.send(responsePacket);
        System.out.println("Sent: " + message);
    }
}
